#ifndef RTU_FUNCTIONS_HPP
#define RTU_FUNCTIONS_HPP

#include "RTUSlave.hpp"

namespace Modbus{

namespace Function {

/* 0x01. 读取线圈. */

class ReadCoils : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int getBit(uint8_t *buffer,unsigned int address) = 0;
    };
public:
    explicit ReadCoils(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x01;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x02. 读取离散量输入. */

class ReadDiscreteInputs : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int getBit(uint8_t *buffer,unsigned int address) = 0;
    };
public:
    explicit ReadDiscreteInputs(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x02;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x03. 读取保持寄存器. */

class ReadHoldingRegister : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int getWord(uint16_t *buffer,unsigned int address) = 0;
    };
public:
    explicit ReadHoldingRegister(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x03;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x04. 读取输入寄存器. */

class ReadInputRegister : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int getWord(uint16_t *buffer,unsigned int address) = 0;
    };
public:
    explicit ReadInputRegister(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x04;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x05. 写单个线圈. */

class WriteCoil : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int setBit(const uint8_t *buffer,unsigned int address) = 0;
    };
public:
    explicit WriteCoil(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x05;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x06. 写单个寄存器. */

class WriteHoldingRegister : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int setWord(const uint16_t *buffer,unsigned int address) = 0;
    };
public:
    explicit WriteHoldingRegister(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x06;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x0F. 写多个线圈. */

class WriteMultipleCoils : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int setBit(const uint8_t *buffer,unsigned int address) = 0;
    };
public:
    explicit WriteMultipleCoils(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x0F;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};

/* 0x10. 写多个寄存器. */

class WriteMultipleHoldingRegisters : public Slave::Function {
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual int setWord(const uint16_t *buffer,unsigned int address) = 0;
    };
public:
    explicit WriteMultipleHoldingRegisters(uint16_t *buffer,unsigned int buffer_wsize,PortableStrategy *portable_strategy,RTUSlave *slave);
    virtual unsigned int getFunctionCode(void);
    virtual int parse(void *pdu,unsigned int size,bool broadcast);
public:
    static const unsigned int FUNCTION_CODE = 0x10;
protected:
    uint16_t *buffer = nullptr;
    unsigned int buffer_wsize = 0;
    PortableStrategy *portable_strategy = nullptr;
};


}


}

#endif
